// Copyright (C) 1953-2023 NUDT
// Verilog module name - stream_mapping   
// Version: V4.3.0.20230309
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         map traffic transmitted by user into TSN traffic identificated by network.
///////////////////////////////////////////////////////////////////////////
 
`timescale 1ns/1ps
module stream_mapping
(
        i_clk               ,
        i_rst_n             ,
                            
        iv_addr             ,  
        iv_wdata            ,  
        i_wr                ,  
        i_rd                ,  
                            
        o_wr                ,  
        ov_addr             ,  
        ov_rdata            ,          
                            
        iv_data             ,
        i_data_wr           ,
                            
        //o_add_tag_flag      ,        
        //ov_ipv              ,
        //ov_flowid           ,
        //o_replication_flag  ,
        //ov_seq_num          ,
		  ov_ipv              ,
        ov_inject_dbufid    ,
        ov_data             ,
        o_data_wr     
);
// I/O
// clk & rst
input                   i_clk                    ;
input                   i_rst_n                  ;  
// pkt input

input       [18:0]     iv_addr                   ;
input       [31:0]     iv_wdata                  ;
input                  i_wr                      ;
input                  i_rd                      ;

output                 o_wr                      ;
output      [18:0]     ov_addr                   ;
output      [31:0]     ov_rdata                  ;  

input      [8:0]        iv_data                  ;
input                   i_data_wr                ;
//output 
//output                  o_add_tag_flag           ;
//output     [2:0]        ov_ipv                   ;
//output     [13:0]       ov_flowid                ;
//output                  o_replication_flag       ;
//output     [15:0]       ov_seq_num               ;
output     [2:0]        ov_ipv                   ;
output     [4:0]        ov_inject_dbufid         ;
output     [8:0]        ov_data                  ;
output                  o_data_wr                ;
//read ram
wire                    w_map_ram_rd_lmt2ram;
wire       [5:0]        wv_map_ram_addr_lmt2ram;
wire       [164:0]      wv_map_ram_rdata_ram2lmt;
wire                    w_map_ram_wr_lmt2ram;
wire       [164:0]      wv_map_ram_wdata_lmt2ram;                     
//five tuple
wire       [103:0]      wv_5tuple_data_mke2lmt;
wire                    w_5tuple_data_wr_mke2lmt;
//frag info
wire                    w_ip_flag_mke2lmt;
wire       [15:0]       wv_identification_mke2lmt;
wire                    w_first_fragment_mke2lmt;
wire                    w_tcp_or_udp_flag_mke2lmt;
wire                    w_tsn_or_standard_mke2lmt;
wire                    w_st_or_rc_mke2lmt;
wire       [4:0]        wv_dbufid_mke2lmt ;

wire       [2:0]        wv_ipv;
wire       [13:0]       wv_flowid;
wire       [15:0]       wv_seq_num;
wire       [4:0]        wv_inject_dbufid;
wire                    w_replication_flag;
wire                    w_hit_lmt2mfo;
wire                    w_lookup_finish_wr_lmt2mfo;

wire                    w_fifo_empty_fifo2mfo;
wire                    w_fifo_rd_mfo2fifo;
wire       [8:0]        wv_fifo_rdata_fifo2mfo;

wire       [5:0]       wv_ram_addr_rwi2ram     ;   
wire       [164:0]     wv_ram_wdata_rwi2ram    ;  
wire                   w_ram_wr_rwi2ram        ;   
wire       [164:0]     wv_ram_rdata_ram2rwi    ;  
wire                   w_ram_rd_rwi2ram        ;

wire                  w_add_tag_flag_mfo2fmo;
wire      [2:0]       wv_ipv_mfo2fmo;
wire      [13:0]      wv_flowid_mfo2fmo;
wire                  w_replication_flag_mfo2fmo;
wire      [15:0]      wv_seq_num_mfo2fmo;
wire      [4:0]       wv_inject_dbufid_mfo2fmo;

wire      [8:0]       wv_data_mfo2fmo  ;
wire                  w_data_wr_mfo2fmo;

command_parse_and_encapsulate_smp command_parse_and_encapsulate_smp_inst
(
.i_clk                    (i_clk                ),                
.i_rst_n                  (i_rst_n              ),      
                                                
.iv_addr                  (iv_addr              ),         
.iv_wdata                 (iv_wdata             ),         
.i_wr                     (i_wr                 ),      
.i_rd                     (i_rd                 ),      
                                                
.o_wr                     (o_wr                 ),      
.ov_addr                  (ov_addr              ),      
.ov_rdata                 (ov_rdata             ),      

.ov_ram_addr              (wv_ram_addr_rwi2ram  ),      
.ov_ram_wdata             (wv_ram_wdata_rwi2ram ),      
.o_ram_wr                 (w_ram_wr_rwi2ram     ),         
.iv_ram_rdata             (wv_ram_rdata_ram2rwi ),      
.o_ram_rd                 (w_ram_rd_rwi2ram     )             
);

map_key_extract map_key_extract_inst(
.i_clk                    (i_clk),
.i_rst_n                  (i_rst_n),

.iv_data                  (iv_data),
.i_data_wr                (i_data_wr),
.ov_5tuple_data           (wv_5tuple_data_mke2lmt),
.o_5tuple_data_wr         (w_5tuple_data_wr_mke2lmt),          
.ov_identification        (wv_identification_mke2lmt),
.o_first_fragment         (w_first_fragment_mke2lmt),
.o_ip_flag                (w_ip_flag_mke2lmt),
.o_tcp_or_udp_flag        (w_tcp_or_udp_flag_mke2lmt),
.o_tsn_or_standard        (w_tsn_or_standard_mke2lmt),
.o_st_or_rc               (w_st_or_rc_mke2lmt       ),
.ov_dbufid                (wv_dbufid_mke2lmt)  
); 

lookup_map_table lookup_map_table_inst(
.i_clk                      (i_clk),
.i_rst_n                    (i_rst_n),
.iv_5tuple_data             (wv_5tuple_data_mke2lmt),
.i_5tuple_data_wr           (w_5tuple_data_wr_mke2lmt),
.iv_identification          (wv_identification_mke2lmt),
.i_first_fragment           (w_first_fragment_mke2lmt),
.i_ip_flag                  (w_ip_flag_mke2lmt),
.i_tcp_or_udp_flag          (w_tcp_or_udp_flag_mke2lmt),
.i_tsn_or_standard          (w_tsn_or_standard_mke2lmt),
.i_st_or_rc                 (w_st_or_rc_mke2lmt       ),
.iv_dbufid                  (wv_dbufid_mke2lmt),   
.o_map_ram_rd               (w_map_ram_rd_lmt2ram),
.ov_map_ram_addr            (wv_map_ram_addr_lmt2ram),
.iv_map_ram_rdata           (wv_map_ram_rdata_ram2lmt),
.o_map_ram_wr               (w_map_ram_wr_lmt2ram),
.ov_map_ram_wdata           (wv_map_ram_wdata_lmt2ram),

.o_add_tag_flag             (w_hit_lmt2mfo             ),
.ov_ipv                     (wv_ipv                    ),
.ov_flowid                  (wv_flowid                 ),
.o_replication_flag         (w_replication_flag        ),
.ov_seq_num                 (wv_seq_num                ),
.ov_inject_dbufid           (wv_inject_dbufid          ),
.o_lookup_finish_wr         (w_lookup_finish_wr_lmt2mfo)
);

mapped_frame_outport mapped_frame_outport_inst(
.i_clk                    (i_clk  ),
.i_rst_n                  (i_rst_n),
                          
.i_add_tag_flag           (w_hit_lmt2mfo             ),
.iv_ipv                   (wv_ipv                    ),
.iv_flowid                (wv_flowid                 ),
.i_replication_flag       (w_replication_flag        ),
.iv_seq_num               (wv_seq_num                ),
.iv_inject_dbufid         (wv_inject_dbufid          ),
.i_lookup_finish_wr       (w_lookup_finish_wr_lmt2mfo),

.i_fifo_empty             (w_fifo_empty_fifo2mfo),
.o_fifo_rd                (w_fifo_rd_mfo2fifo),
.iv_fifo_rdata            (wv_fifo_rdata_fifo2mfo),
 
.o_add_tag_flag           (w_add_tag_flag_mfo2fmo     ),	
.ov_ipv                   (wv_ipv_mfo2fmo             ),
.ov_flowid                (wv_flowid_mfo2fmo          ),
.o_replication_flag       (w_replication_flag_mfo2fmo ),
.ov_seq_num               (wv_seq_num_mfo2fmo         ),   
.ov_inject_dbufid         (wv_inject_dbufid_mfo2fmo   ),
 
.ov_data                  (wv_data_mfo2fmo  ),
.o_data_wr                (w_data_wr_mfo2fmo)
);

frame_modify frame_modify_inst
(
       .i_clk               (i_clk             ),
       .i_rst_n             (i_rst_n           ),
                                             
       .i_add_tag_flag      (w_add_tag_flag_mfo2fmo    ),
       .iv_ipv              (wv_ipv_mfo2fmo            ),
       .iv_flowid           (wv_flowid_mfo2fmo         ),
       .i_replication_flag  (w_replication_flag_mfo2fmo),
       .iv_seq_num          (wv_seq_num_mfo2fmo        ),
       .iv_inject_dbufid    (wv_inject_dbufid_mfo2fmo  ),
                                             
       .iv_data             (wv_data_mfo2fmo           ),
       .i_data_wr           (w_data_wr_mfo2fmo         ),
                     
       .ov_data             (ov_data         ),       
       .o_data_wr           (o_data_wr       ),  
       .ov_ipv              (ov_ipv          ),       
       .ov_inject_dbufid    (ov_inject_dbufid)     
);
//altera ip

syncfifo_showahead_aclr_w9d128 syncfifo_showahead_aclr_w9d128_inst(
.data      (iv_data), 
.wrreq     (i_data_wr),
.rdreq     (w_fifo_rd_mfo2fifo),
.clock     (i_clk),
.aclr      (!i_rst_n),
.q         (wv_fifo_rdata_fifo2mfo),   
.usedw     (),
.full      (),
.empty     (w_fifo_empty_fifo2mfo) 
);

tdpr_singleclock_rdenab_outputaclr_w165d64 tdpr_singleclock_rdenab_outputaclr_w165d64_inst(
.aclr      (!i_rst_n               ),  //asynchronous reset(high active)
.data_a    (wv_ram_wdata_rwi2ram),    //  ram_input.datain_a
.data_b    (wv_map_ram_wdata_lmt2ram),    //           .datain_b
.address_a (wv_ram_addr_rwi2ram), //           .address_a
.address_b (wv_map_ram_addr_lmt2ram), //           .address_b
.wren_a    (w_ram_wr_rwi2ram),    //           .wren_a
.wren_b    (w_map_ram_wr_lmt2ram),    //           .wren_b
.clock     (i_clk),     //           .clock
.rden_a    (w_ram_rd_rwi2ram),    //           .rden_a
.rden_b    (w_map_ram_rd_lmt2ram),    //           .rden_b
.q_a       (wv_ram_rdata_ram2rwi),       // ram_output.dataout_a
.q_b       (wv_map_ram_rdata_ram2lmt)        //           .dataout_b
);  

//xilinx ip
/*
syncfifo_showahead_aclr_w9d128 syncfifo_showahead_aclr_w9d128_inst(
    .din  (iv_data  ), 
    .wr_en (i_data_wr),
    .rd_en (w_fifo_rd_mfo2fifo),
    .clk   (i_clk),
    .srst   (!i_rst_n), 
    .dout  (wv_fifo_rdata_fifo2mfo),    
    .data_count (),
    .full  (), 
    .empty (w_fifo_empty_fifo2mfo) 
);

truedualportram_w165d64 truedualportram_w165d64_inst(
.regcea            (1'b1),
.regceb            (1'b1),

.rsta              (!i_rst_n),
.rstb              (!i_rst_n),
                                                              
.dina              (wv_ram_wdata_rwi2ram),                                          
.dinb              (wv_map_ram_wdata_lmt2ram),                                  
.addra             (wv_ram_addr_rwi2ram),                           
.addrb             (wv_map_ram_addr_lmt2ram),                           
.wea               (w_ram_wr_rwi2ram),                             
.web               (w_map_ram_wr_lmt2ram),                                
.clka              (i_clk),
.clkb              (i_clk),               
.ena               (1'b1),                             
.enb               (1'b1),                          
.douta             (wv_ram_rdata_ram2rwi),                     
.doutb             (wv_map_ram_rdata_ram2lmt)           
);  
*/
(*MARK_DEBUG="true"*) reg  [15:0]  rv_pkt_counter/*synthesis noprune*/;
(*MARK_DEBUG="true"*) reg  r_data_valid;
always @(posedge i_clk or negedge i_rst_n) begin
    if (!i_rst_n) begin
        rv_pkt_counter <= 16'b0;
		r_data_valid    <=  1'b0;
    end
    else begin
	    r_data_valid <= i_data_wr;
        if((!r_data_valid) && i_data_wr)begin
			rv_pkt_counter <= rv_pkt_counter + 1'b1;
        end
        else begin
            rv_pkt_counter <=  rv_pkt_counter;
        end		
	end	
end
endmodule